﻿/// <summary>
/// <Filename>: Motion_XIAN.cs
/// Author: Jiang Xiaolong
/// Created: 2015.01.30
/// Version: 1.0
/// Company: Sunnytech
/// Function: XIAN表格运动信息处理类
///
/// Changed By:
/// Modification Time:
/// Discription:
/// <summary>
using UnityEngine;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Reflection;
using System.Collections;
using Motion.MotionPlatform.Tools;

namespace Motion.MotionPlatform
{
	//引出线运动类
	public class DoLabelMotion : IMotion
	{
		//默认为Active
		public CurrentState State
		{
			get { return _state; }
			set { _state = value; }
		}
		private CurrentState _state = CurrentState.Active;
		//速率
		public float SpeedRate
		{
			get { return Motion_Data.SpeedRate; }
			set { Motion_Data.SpeedRate = value; }
		}
		//时间参数
		//正常速率时间
		public float StandardTime
		{
			get { return _standardTime; }
			set { _standardTime = value; }
		}
		private float _standardTime = 0f;
		//运动开始时间
		public float StartTime
		{
			get { return _startTime; }
			set { _startTime = value; }
		}
		private float _startTime = 0f;
		//运动结束时间
		public float EndTime
		{
			get { return _endTime; }
			set { _endTime = value; }
		}
		private float _endTime = 0f;

		//暂停状态
		public bool PauseControl
		{
			get { return Motion_Data.PauseControl; }
			set { Motion_Data.PauseControl = value; }
		}

		public static List<int> Label_layer = new List<int>();
		public static List<string> Label_obj = new List<string>();
		public static List<string> Label_name = new List<string>();
		public static List<Vector3> Label_pos = new List<Vector3>();

		public static List<int> Label_layer2 = new List<int>();
		public static List<string> Label_obj2 = new List<string>();
		public static List<string> Label_name2 = new List<string>();
		public static List<Vector3> Label_pos2 = new List<Vector3>();

		//显示方式： true--同时显示; false--顺序播放
		public bool showType = true;
		//顺序播放的次序控制
		public int labelCount;
		//Tips暂停控制中间时间值
		private float _pauseTimeRecorder = 0f;

		//结构初始化
		public void Init()
		{
			Type _t = Motion_TypeGet.MotionTypeGet("doMoldLable");
			if (!MotionPlatformData.doLableClass && _t != null)
			{
				MotionPlatformData.doLableClass = (MonoBehaviour)GameObject.FindObjectOfType(_t);
			}

			if (MotionPlatformData.doLableClass && _t != null)
			{
				FieldInfo fieldInfo = _t.GetField("outlineOn");
				fieldInfo.SetValue(MotionPlatformData.doLableClass, true);
			}
			else
			{
				Debug.LogError("反射失败：doMoldLable.outlineOn变量");
			}

			labelCount = 0;

			//同时显示
			if (showType)
			{
				for (int i = 0; i < Label_obj2.Count; i++)
				{
					Label_layer.Add(Label_layer2[i]);
					Label_obj.Add(Label_obj2[i]);
					Label_name.Add(Label_name2[i]);
					Label_pos.Add(Label_pos2[i]);
				}
			}
			//顺序显示
			else
			{

			}
		}



		//暂停控制
		public void Pause(bool play_status)
		{

		}

		//速率控制
		public void ChangeRate(float current_rate, float current_time)
		{
			EndTime = current_time + (EndTime - current_time) * SpeedRate / current_rate;
		}

		//运动
		public void Move(float current_time, float speed_rate, float delta_time)
		{

		}

		//	//变速后的时间比率
		//	private float TimeRate(float current_time)
		//	{
		//		currentTimeRate = startTimeRate + (current_time - postTime) / restTime;
		//		return currentTimeRate;
		//	}

		//时间管理
		public bool TimesUp(float current_time)
		{
			//只在教的时候显示
			if(MotionPlatformData.currentMotion == MotionPlatformState.Teaching)
			{
				if (showType)
				{
					if (current_time > EndTime)
					{
						return true;
					}
					else
						return false;
				}
				else
				{
					if (!Motion_Data.isEditor)
					{
						if (PauseControl)
						{
							//暂停时不断增加，因为语音不会暂停
							_pauseTimeRecorder += Time.deltaTime;
						}
					}

					if ((current_time + _pauseTimeRecorder) > EndTime && (labelCount == Label_obj2.Count))
					{
						return true;
					}
					else
						return false;
				}
			}
			else
			{
				return true;
			}
		}

		//后处理，主要是位置修正
		public void PostProcess()
		{
			Type _t = Motion_TypeGet.MotionTypeGet("doMoldLable");
			if (!MotionPlatformData.doLableClass && _t != null)
			{
				MotionPlatformData.doLableClass = (MonoBehaviour)GameObject.FindObjectOfType(_t);
			}

			if (MotionPlatformData.doLableClass && _t != null)
			{
				FieldInfo fieldInfo = _t.GetField("outlineOn");
				fieldInfo.SetValue(MotionPlatformData.doLableClass, false);
			}
			else
			{
				Debug.LogError("反射失败：doMoldLable.outlineOn变量");
			}
		}

		//最后没运行的时间修正
		private void TimeCorrection(float delta_time, float speed_rate)
		{

		}
	}

	/// <summary>
	/// XIAN运动信息提取管理类，相当于工厂；
	/// </summary>
	public class Motion_XIANInfoManager : IMotionInfoManager
	{
		/// <summary>
		/// 信息获取函数，用反射的方式创建Tips相应的解析类；
		/// </summary>
		/// <param name="motion_symbol">当前运动标识符；</param>
		/// <param name="data_row">当前传入的Excel数据行；</param>
		/// <param name="row_id">当前行对应ID号；</param>
		/// <param name="group_table">当前Group数据表；</param>
		/// <param name="motion_list">简单运动类列表；</param>
		/// <param name="complex_motion_list">复合运动类列表；</param>
		/// <returns>解析是否正确；</returns>
		public bool InfoGet(string motion_symbol, int state, DataRow data_row, string row_id, DataTable group_table, IList<IMotion> motion_list, IList<IList<IMotion>> complex_motion_list)
		{
			string motionTypeID = "ONLY";
			if (Motion_Data.MotionFunctionAllow(motion_symbol, motionTypeID, state))
			{
				if (Motion_Data.MotionFunctionClassDic[motion_symbol].ContainsKey(motionTypeID))
				{
					Type _t = Motion_TypeGet.MotionTypeGet("Motion.MotionPlatform." + Motion_Data.MotionFunctionClassDic[motion_symbol][motionTypeID]);
					//实例化相应的解析类
					IMotionFunctionInfo infoInstance = (IMotionFunctionInfo)Activator.CreateInstance(_t);

					////将Excel中参数转换成参数表里面的数据
					//Motion_Compute.ExcelDataAnalysis(ref data_row);
					return infoInstance.InfoGet(data_row, row_id, group_table, motion_list, complex_motion_list);
				}
				else
				{
					Debug.LogError("XIAN运动标志符：" + motionTypeID + "，不含有该运动标志符对应的解析类，请询问相关程序猿！");
					return false;
				}
			}
			else
			{
				return true;
			}
		}
	}

	/// <summary>
	/// 引出线运动；
	/// </summary>
	public class Motion_XIAN_Only : IMotionFunctionInfo
	{
		public bool InfoGet(DataRow data_row, string row_id, DataTable group_table, IList<IMotion> motion_list, IList<IList<IMotion>> complex_motion_list)
		{
			DoLabelMotion _xianMotion = new DoLabelMotion();
			bool is_right = true;

			DoLabelMotion.Label_layer.Clear();
			DoLabelMotion.Label_name.Clear();
			DoLabelMotion.Label_obj.Clear();
			DoLabelMotion.Label_pos.Clear();

			DoLabelMotion.Label_layer2.Clear();
			DoLabelMotion.Label_name2.Clear();
			DoLabelMotion.Label_obj2.Clear();
			DoLabelMotion.Label_pos2.Clear();

			//物体信息
			string obj = (string)data_row[2].ToString();
			//		ExcelOperator excelReader = new ExcelOperator();
			//		DataTable sheetTable = excelReader.ExcelReader(MotionPara.taskRootPath + MotionPara.taskName + "/XIAN.xls", obj);

			JsonOperator jo2 = new JsonOperator();
			DataTable sheetTable = jo2.JsonReader(MotionPlatformData.taskRootPath + MotionPlatformData.taskName + "/XIAN.json", obj);

			for (int j = 0; j < sheetTable.Rows.Count; j++)
			{
				DataRow dr = sheetTable.Rows[j];

				DoLabelMotion.Label_layer2.Add(int.Parse(dr[0].ToString()));
				DoLabelMotion.Label_name2.Add(dr[1].ToString());
				DoLabelMotion.Label_obj2.Add(dr[2].ToString());

				DoLabelMotion.Label_pos2.Add(new Vector3(0, 0, 0));
			}

			//时间
			float time_tmp = Motion_Compute.FloatConversion(data_row[3].ToString(), ref is_right);
			if (!is_right)
			{
				if (Motion_Data.isEditor)
				{
					Debug.LogError(ErrorLocation.Locate("XIAN", "TIME", row_id) + "，引出线的时间填写错误！");
				}
				return false;
			}
			_xianMotion.StandardTime = time_tmp;
			_xianMotion.EndTime = _xianMotion.StandardTime / _xianMotion.SpeedRate;


			//显示方式
			string showType_tmp = data_row[4].ToString();
			if (showType_tmp.ToUpper() == "TRUE")
			{
				_xianMotion.showType = true;
			}
			else if (showType_tmp.ToUpper() == "FALSE")
			{
				_xianMotion.showType = false;
			}
			else
			{
				Debug.LogError(ErrorLocation.Locate("XIAN", "SHOWTYPE", row_id) + "，引出线的显示方式填写错误！");
			}

			//耦合太强修改，应用反射的方式直接调用想用的函数！
			Type _t = Motion_TypeGet.MotionTypeGet("doMoldLable");
			if (!MotionPlatformData.doLableClass && _t != null)
			{
				MotionPlatformData.doLableClass = (MonoBehaviour)GameObject.FindObjectOfType(_t);
			}

			if (MotionPlatformData.doLableClass && _t != null)
			{
				MethodInfo methodInfo = _t.GetMethod("showLabelType");
				BindingFlags flag = BindingFlags.Public | BindingFlags.Instance;
				object[] para = new object[] { data_row[2].ToString(), true };
				methodInfo.Invoke(MotionPlatformData.doLableClass, flag, Type.DefaultBinder, para, null);
			}
			else
			{
				Debug.LogError("反射失败：doMoldLable.showLabelType函数");
				return false;
			}

			motion_list.Add(_xianMotion);

			return true;
		}

	}
}
